home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / cdrecord / wm_packet.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-30  |  6.2 KB  |  238 lines

  1. /* @(#)wm_packet.c    1.13 00/07/30 Copyright 1995, 1997 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)wm_packet.c    1.13 00/07/30 Copyright 1995, 1997 J. Schilling";
  5. #endif
  6. /*
  7.  *    CDR write method abtraction layer
  8.  *    packet writing intercace routines
  9.  *
  10.  *    Copyright (c) 1995, 1997 J. Schilling
  11.  */
  12. /*
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2, or (at your option)
  16.  * any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. #include <mconfig.h>
  29. #include <stdio.h>
  30. #include <standard.h>
  31. #include <stdxlib.h>
  32. #include <unixstd.h>
  33. /*#include <string.h>*/
  34. #include <sys/types.h>
  35. #include <utypes.h>
  36. #include <schily.h>
  37.  
  38. #include <scg/scsitransp.h>
  39. #include "cdrecord.h"
  40.  
  41. extern    int    debug;
  42. extern    int    verbose;
  43. extern    int    lverbose;
  44.  
  45. extern    char    *buf;            /* The transfer buffer */
  46.  
  47. EXPORT    int    write_packet_data __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));
  48.  
  49. EXPORT int
  50. write_packet_data(scgp, dp, track, trackp)
  51.     SCSI    *scgp;
  52.     cdr_t    *dp;
  53.     int    track;
  54.     track_t    *trackp;
  55. {
  56.     int    f;
  57.     int    isaudio;
  58.     long    startsec;
  59.     long    bytes_read = 0;
  60.     long    bytes    = 0;
  61.     long    savbytes = 0;
  62.     int    count;
  63.     long    tracksize;
  64.     int    secsize;
  65.     int    secspt;
  66.     int    bytespt;
  67.     long    amount;
  68.     int    pad;
  69.     int    bswab;
  70.     int    retried;
  71.     long    nextblock; 
  72.     int    bytes_to_read;
  73.     BOOL    neednl    = FALSE;
  74.     BOOL    islast    = FALSE;
  75.     char    *bp    = buf;
  76.  
  77.     f = trackp->f;
  78.     isaudio = is_audio(trackp);
  79.     tracksize = trackp->tracksize;
  80.     startsec = trackp->trackstart;
  81.  
  82.     secsize = trackp->secsize;
  83.     secspt = trackp->secspt;
  84.     bytespt = secsize * secspt;
  85.     
  86.     pad = !isaudio && is_pad(trackp);    /* Pad only data tracks */
  87.     bswab = isaudio && is_swab(trackp);    /* Swab only audio tracks */
  88.  
  89.     if (debug) {
  90.         printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%d\n",
  91.             secsize, secspt, bytespt, isaudio, pad);
  92.     }
  93.  
  94.     if (lverbose) {
  95.         if (tracksize > 0)
  96.             printf("\rTrack %02d:   0 of %3ld MB written.",
  97.                    track, tracksize >> 20);
  98.         else
  99.             printf("\rTrack %02d:   0 MB written.", track);
  100.         flush();
  101.         neednl = TRUE;
  102.     }
  103.  
  104.     do {
  105.         bytes_to_read = bytespt;
  106.         if (tracksize > 0) {
  107.             bytes_to_read = tracksize - bytes_read;
  108.             if (bytes_to_read > bytespt)
  109.                 bytes_to_read = bytespt;
  110.         }
  111.         count = get_buf(f, &bp, bytes_to_read);
  112.         if (count < 0)
  113.             comerr("read error on input file\n");
  114.         if (count == 0)
  115.             break;
  116.         bytes_read += count;
  117.         if (tracksize >= 0 && bytes_read >= tracksize) {
  118.             count -= bytes_read - tracksize;
  119.             if (trackp->padsize == 0 || (bytes_read/secsize) >= 300)
  120.                 islast = TRUE;
  121.         }
  122.  
  123.         if (bswab)
  124.             swabbytes(bp, count);
  125.  
  126.         if (count < bytespt) {
  127.             if (debug) {
  128.                 printf("\nNOTICE: reducing block size for last record.\n");
  129.                 neednl = FALSE;
  130.             }
  131.  
  132.             if ((amount = count % secsize) != 0) {
  133.                 amount = secsize - amount;
  134.                 fillbytes(&bp[count], amount, '\0');
  135.                 count += amount;
  136.                 printf("\nWARNING: padding up to secsize.\n");
  137.                 neednl = FALSE;
  138.             }
  139.             if (is_packet(trackp) && trackp->pktsize > 0) {
  140.                 if (count < bytespt) {
  141.                     amount = bytespt - count;
  142.                     fillbytes(&bp[count], amount, '\0');
  143.                     count += amount;
  144.                     printf("\nWARNING: padding remainder of packet.\n");
  145.                     neednl = FALSE;
  146.                 }
  147.             }
  148.             bytespt = count;
  149.             secspt = count / secsize;
  150.             if (trackp->padsize == 0 || (bytes_read/secsize) >= 300)
  151.                 islast = TRUE;
  152.         }
  153.  
  154.         retried = 0;
  155.         retry:
  156.         /* XXX Fixed-packet writes can be very slow*/
  157.         if (is_packet(trackp) && trackp->pktsize > 0)
  158.             scg_settimeout(scgp, 100);
  159.         /* XXX */
  160.         if (is_packet(trackp) && trackp->pktsize == 0) {
  161.             if ((*dp->cdr_next_wr_address)(scgp, track, trackp, &nextblock) == 0) {
  162.                 /*
  163.                  * Some drives (e.g. Ricoh MPS6201S) do not
  164.                  * increment the Next Writable Address value to
  165.                  * point to the beginning of a new packet if
  166.                  * their write buffer has underflowed.
  167.                  */
  168.                 if (retried && nextblock == startsec) {
  169.                     startsec += 7; 
  170.                 } else {
  171.                     startsec = nextblock;
  172.                 }
  173.             }
  174.         }
  175.  
  176.         amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
  177.         if (amount < 0) {
  178.             if (is_packet(trackp) && trackp->pktsize == 0 && !retried) {
  179.                 printf("%swrite track data: error after %ld bytes, retry with new packet\n",
  180.                     neednl?"\n":"", bytes);
  181.                 retried = 1;
  182.                 neednl = FALSE;
  183.                 goto retry;
  184.             }
  185.             printf("%swrite track data: error after %ld bytes\n",
  186.                             neednl?"\n":"", bytes);
  187.             return (-1);
  188.         }
  189.         bytes += amount;
  190.         startsec += amount / secsize;
  191.  
  192.         if (lverbose && (bytes >= (savbytes + 0x100000))) {
  193.             int    fper;
  194.  
  195.             printf("\rTrack %02d: %3ld", track, bytes >> 20);
  196.             if (tracksize > 0)
  197.                 printf(" of %3ld MB", tracksize >> 20);
  198.             else
  199.                 printf(" MB");
  200.             printf(" written");
  201.             fper = fifo_percent(TRUE);
  202.             if (fper >= 0)
  203.                 printf(" (fifo %3d%%)", fper);
  204.             printf(".");
  205.             savbytes = (bytes >> 20) << 20;
  206.             flush();
  207.             neednl = TRUE;
  208.         }
  209.     } while (tracksize < 0 || bytes_read < tracksize);
  210.  
  211.     if ((bytes / secsize) < 300) {
  212.         amount = roundup(trackp->padsize, secsize);
  213.         if (((bytes+amount) / secsize) < 300)
  214.             trackp->padsize = 300 * secsize - bytes;
  215.     }
  216.     if (trackp->padsize) {
  217.         if (neednl) {
  218.             printf("\n");
  219.             neednl = FALSE;
  220.         }
  221.         if ((trackp->padsize >> 20) > 0) {
  222.             neednl = TRUE;
  223.         } else if (lverbose) {
  224.             printf("Track %02d: writing %3ld KB of pad data.\n",
  225.                         track, trackp->padsize >> 10);
  226.             neednl = FALSE;
  227.         }
  228.         pad_track(scgp, dp, track, trackp, startsec, trackp->padsize,
  229.                     TRUE, &amount);
  230.         bytes += amount;
  231.         startsec += amount / secsize;
  232.     }
  233.     printf("%sTrack %02d: Total bytes read/written: %ld/%ld (%ld sectors).\n",
  234.            neednl?"\n":"", track, bytes_read, bytes, bytes/secsize);
  235.     return 0;
  236. }
  237.  
  238.